import { Math } from "core-js";
import * as THREE from "three";
// 引入Three.js扩展库
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
// const {Matrix4} = createRequire('three')
// const {Vector3} = createRequire('three')
// const {Vector2} = createRequire('three')

import { Matrix4, Vector3, Vector2 } from "three";

/**
 * 添加筒体
 * @param {*} P1X 1点坐标X
 * @param {*} P1Y 1点坐标y
 * @param {*} P1Z 1点坐标z
 * @param {*} P2X 2点坐标X
 * @param {*} P2Y 2点坐标y
 * @param {*} P2Z 2点坐标z
 * @param {*} length 筒体长度
 * @param {*} diameter 筒体直径
 * @param {*} material 材质
 * @returns
 */
export function AddCylinder(
  P1X,
  P1Y,
  P1Z,
  P2X,
  P2Y,
  P2Z,
  length,
  diameter,
  material
) {
  var geometry = new THREE.CylinderGeometry(
    diameter * 0.5,
    diameter * 0.5,
    length,
    32
  );
  var cylinder = new THREE.Mesh(geometry, material);
  cylinder.castShadow = true; // 投射阴影
  var CenterX = 0.5 * (P1X + P2X);
  var CenterY = 0.5 * (P1Y + P2Y);
  var CenterZ = 0.5 * (P1Z + P2Z);
  cylinder.translateX(CenterX);
  cylinder.translateY(CenterY);
  cylinder.translateZ(CenterZ);
  //移动到标准位置
  /*   cylinder.rotateZ(-Math.PI * 0.5);
    cylinder.translateY(length * 0.5); */
  //计算转角
  var RotateAngelZ = new THREE.Vector2(P2X - P1X, P2Y - P1Y);
  cylinder.rotateZ(RotateAngelZ.angle() - Math.PI / 2);
  /*   //移动到1点
    cylinder.translateX(-P1Y);
    cylinder.translateY(P1X);
    cylinder.translateZ(P1Z); */

  return cylinder;
}

export function AddCylinder2(
  P1X,
  P1Y,
  P1Z,
  P2X,
  P2Y,
  P2Z,
  length,
  diameter,
  material
) {
  var geometry = new THREE.CylinderGeometry(
    diameter * 0.5,
    diameter * 0.5,
    length,
    32
  );
  var cylinder = new THREE.Mesh(geometry, material);
  cylinder.castShadow = true; // 投射阴影
  //初始化管口密封面位置
  cylinder.position.set(0, -length * 0.5, 0);
  let wrapper = new THREE.Object3D();
  wrapper.add(cylinder);
  var quaternion = new THREE.Quaternion();
  quaternion.setFromUnitVectors(
    new Vector3(0, 1, 0),
    new Vector3(P1X - P2X, P1Y - P2Y, P1Z - P2Z).normalize()
  );
  wrapper.rotation.setFromQuaternion(quaternion);
  var MT43 = new THREE.Matrix4().setPosition(P1X, P1Y, P1Z);
  wrapper.applyMatrix4(MT43);

  return wrapper;
}
/**
 * 生成同心异径体
 * @param {*} P1X 大端中心X
 * @param {*} P1Y 大端中心Y
 * @param {*} P1Z 大端中心Z
 * @param {*} P2X 小端中心X
 * @param {*} P2Y 小端中心Y
 * @param {*} P2Z 小端中心Z
 * @param {*} A 长度
 * @param {*} B 大端直径
 * @param {*} C 小端直径
 * @param {*} material 材质
 * @returns
 */
export function AddCone(P1X, P1Y, P1Z, P2X, P2Y, P2Z, A, B, C, material) {
  var geometry = new THREE.CylinderGeometry(C * 0.5, B * 0.5, A, 32);
  var cylinder = new THREE.Mesh(geometry, material);
  cylinder.castShadow = true; // 投射阴影
  var CenterX = 0.5 * (P1X + P2X);
  var CenterY = 0.5 * (P1Y + P2Y);
  var CenterZ = 0.5 * (P1Z + P2Z);
  cylinder.translateX(CenterX);
  cylinder.translateY(CenterY);
  cylinder.translateZ(CenterZ);
  //移动到标准位置
  /*   cylinder.rotateZ(-Math.PI * 0.5);
    cylinder.translateY(length * 0.5); */
  //计算转角
  var RotateAngelZ = new THREE.Vector2(P2X - P1X, P2Y - P1Y);
  cylinder.rotateZ(RotateAngelZ.angle() - Math.PI / 2);
  /*   //移动到1点
    cylinder.translateX(-P1Y);
    cylinder.translateY(P1X);
    cylinder.translateZ(P1Z); */

  return cylinder;
}
/**
 * 添加地面
 * @param {*} width 地面宽度
 * @param {*} height 地面长度
 * @param {*} height 顶平面标高
 * @param {*} planeMaterial 材质
 * @returns
 */
export function AddGround(width, height, TopEL, planeMaterial) {
  let planeGeometry = new THREE.PlaneGeometry(width, height, 1, 1); // 平面网格
  let plane = new THREE.Mesh(planeGeometry, planeMaterial);
  plane.rotation.x = -0.5 * Math.PI;
  plane.position.x = 0;
  plane.position.y = TopEL - 0.001;
  plane.position.z = 0;
  plane.receiveShadow = true;
  return plane;
}

/**
 * 此函数用于生成封头
 * @param {*} diameter 封头直径
 * @param {*} Centerx 切线圆中心点X
 * @param {*} Centery 切线圆中心点Y
 * @param {*} Centerz 切线圆中心点Z
 * @param {*} material 材质
 * @param {*} RotateAngelX X方向旋转角度
 * @param {*} RotateAngelY Y方向旋转角度
 * @param {*} RotateAngelZ Z方向旋转角度
 * @returns
 */
export function AddHead(
  diameter,
  Centerx,
  Centery,
  Centerz,
  material,
  RotateAngelX,
  RotateAngelY,
  RotateAngelZ
) {
  var geometry = new THREE.SphereGeometry(diameter * 0.5, 32, 32);
  var Head = new THREE.Mesh(geometry, material);
  Head.castShadow = true; // 投射阴影
  Head.scale.set(0.5, 1, 1);
  Head.translateX(Centerx);
  Head.translateY(Centery);
  Head.translateZ(Centerz);
  Head.rotateX(RotateAngelX);
  Head.rotateY(RotateAngelY);
  Head.rotateZ(RotateAngelZ);
  return Head;
}

/**
 * 此函数用于生成封头，仅支持沿Z轴旋转
 * @param {*} P1X 切线圆中心点X
 * @param {*} P1Y 切线圆中心点Y
 * @param {*} P1Z 切线圆中心点Z
 * @param {*} P2X 端点X
 * @param {*} P2Y 端点Y
 * @param {*} P2Z 端点Z，此数据无用
 * @param {*} A 封头直径
 * @param {*} B 短轴高度
 * @param {*} material 材质
 * @returns
 */
export function AddHead2(P1X, P1Y, P1Z, P2X, P2Y, P2Z, A, B, material) {
  var geometry2 = new THREE.SphereGeometry(A * 0.5, 32, 32);
  var Head2 = new THREE.Mesh(geometry2, material);
  Head2.castShadow = true; // 投射阴影
  Head2.translateX(P1X);
  Head2.translateY(P1Y);
  Head2.translateZ(P1Z);
  var ScaleX = (B * 2) / A;
  Head2.scale.set(ScaleX, 1, 1);
  var RotateAngelZ = new THREE.Vector2(P2X - P1X, P2Y - P1Y);
  Head2.rotateZ(RotateAngelZ.angle());
  return Head2;
}

/**
 * 基于8个顶点生成6面体，此函数主要用于测试
 * @param {*} P1X
 * @param {*} P1Y
 * @param {*} P1Z
 * @param {*} P2X
 * @param {*} P2Y
 * @param {*} P2Z
 * @param {*} P3X
 * @param {*} P3Y
 * @param {*} P3Z
 * @param {*} P4X
 * @param {*} P4Y
 * @param {*} P4Z
 * @param {*} A
 * @param {*} B
 * @param {*} C
 * @param {*} D
 * @param {*} E
 * @param {*} material
 * @returns
 */

/**
 * 基于8个顶点生成6面体，此函数主要用于测试
 * @param {*} P1X
 * @param {*} P1Y
 * @param {*} P1Z
 * @param {*} P2X
 * @param {*} P2Y
 * @param {*} P2Z
 * @param {*} P3X
 * @param {*} P3Y
 * @param {*} P3Z
 * @param {*} P4X
 * @param {*} P4Y
 * @param {*} P4Z
 * @param {*} A
 * @param {*} B
 * @param {*} C
 * @param {*} D
 * @param {*} E
 * @param {*} material
 * @returns
 */
export function AddSixPlan2(
  P1X,
  P1Y,
  P1Z,
  P2X,
  P2Y,
  P2Z,
  P3X,
  P3Y,
  P3Z,
  P4X,
  P4Y,
  P4Z,
  A,
  B,
  C,
  D,
  E,
  material
) {
  let wrapper = new THREE.Object3D();
  var cubeGeometry = new THREE.BoxGeometry(B, A, C, 10, 10, 10);
  var cube = new THREE.Mesh(cubeGeometry, material);
  // 次轴调整 （3点和4点对应短边两个端点）
  var quaternion = new THREE.Quaternion();
  quaternion.setFromUnitVectors(
    new Vector3(0, 0, 1),
    new Vector3(P3X - P4X, 0, P3Z - P4Z).normalize()
  );
  // console.log("🚀 ~ file: equipment.js:237 ~ AddSixPlan2 ~ quaternion:", quaternion)
  cube.applyQuaternion(quaternion);
  // 主轴调整
  var quaternion2 = new THREE.Quaternion();
  quaternion2.setFromUnitVectors(
    new Vector3(0, 1, 0),
    new Vector3(P2X - P1X, P2Y - P1Y, P2Z - P1Z).normalize()
  );
  cube.applyQuaternion(quaternion2);
  cube.translateY(0.5 * A);
  wrapper.add(cube);

  //外层位置调整
  var MT43 = new THREE.Matrix4().setPosition(P1X, P1Y, P1Z);
  wrapper.applyMatrix4(MT43);

  return wrapper;
}

/**
 * 生成鞍座
 * @param {*} P1X 放置点X
 * @param {*} P1Y 放置点Y
 * @param {*} P1Z 放置点Z
 * @param {*} P2X 另一面的X
 * @param {*} P2Y 另一面的Y
 * @param {*} P2Z 另一面的Z
 * @param {*} P3X 放置面的第二参考点X，用于确定方向
 * @param {*} P3Y 放置面的第二参考点Y，用于确定方向
 * @param {*} P3Z 放置面的第二参考点Z，用于确定方向
 * @param {*} P4X 放置面的第三参考点X，用于确定方向
 * @param {*} P4Y 放置面的第三参考点Y，用于确定方向
 * @param {*} P4Z 放置面的第三参考点Z，用于确定方向
 * @param {*} A 鞍座参数A
 * @param {*} B 鞍座参数B
 * @param {*} C 鞍座参数C
 * @param {*} D 鞍座参数D
 * @param {*} E 鞍座参数E
 * @param {*} material 材质
 * @returns
 */
export function AddPyramid(
  P1X,
  P1Y,
  P1Z,
  P2X,
  P2Y,
  P2Z,
  P3X,
  P3Y,
  P3Z,
  P4X,
  P4Y,
  P4Z,
  A,
  B,
  C,
  D,
  E,
  material
) {
  var bgeometry = new THREE.BufferGeometry();
  // 每六个坐标，四个点形成一个平面，6个平面合并成封闭的一个立方形
  var vertices = new Float32Array([
    +0.5 * C,
    0.5 * E,
    +0.5 * D,
    -0.5 * C,
    0.5 * E,
    +0.5 * D,
    -0.5 * A,
    -0.5 * E,
    +0.5 * B,
    +0.5 * C,
    0.5 * E,
    +0.5 * D,
    -0.5 * A,
    -0.5 * E,
    +0.5 * B,
    +0.5 * A,
    -0.5 * E,
    +0.5 * B, // 第一个平面（左）
    +0.5 * C,
    0.5 * E,
    +0.5 * D,
    +0.5 * A,
    -0.5 * E,
    +0.5 * B,
    +0.5 * A,
    -0.5 * E,
    -0.5 * B,
    +0.5 * C,
    0.5 * E,
    +0.5 * D,
    +0.5 * A,
    -0.5 * E,
    -0.5 * B,
    +0.5 * C,
    0.5 * E,
    -0.5 * D, // 第二个平面（右）
    -0.5 * C,
    0.5 * E,
    +0.5 * D,
    -0.5 * C,
    0.5 * E,
    -0.5 * D,
    -0.5 * A,
    -0.5 * E,
    -0.5 * B,
    -0.5 * C,
    0.5 * E,
    +0.5 * D,
    -0.5 * A,
    -0.5 * E,
    -0.5 * B,
    -0.5 * A,
    -0.5 * E,
    +0.5 * B, // 第三个平面（后）
    -0.5 * C,
    0.5 * E,
    -0.5 * D,
    +0.5 * C,
    0.5 * E,
    -0.5 * D,
    +0.5 * A,
    -0.5 * E,
    -0.5 * B,
    -0.5 * C,
    0.5 * E,
    -0.5 * D,
    +0.5 * A,
    -0.5 * E,
    -0.5 * B,
    -0.5 * A,
    -0.5 * E,
    -0.5 * B, // 第四个平面（前）
    +0.5 * C,
    0.5 * E,
    -0.5 * D,
    -0.5 * C,
    0.5 * E,
    -0.5 * D,
    -0.5 * C,
    0.5 * E,
    +0.5 * D,
    +0.5 * C,
    0.5 * E,
    -0.5 * D,
    -0.5 * C,
    0.5 * E,
    +0.5 * D,
    +0.5 * C,
    0.5 * E,
    +0.5 * D, // 第五个平面（下）
    +0.5 * A,
    -0.5 * E,
    +0.5 * B,
    -0.5 * A,
    -0.5 * E,
    +0.5 * B,
    -0.5 * A,
    -0.5 * E,
    -0.5 * B,
    +0.5 * A,
    -0.5 * E,
    +0.5 * B,
    -0.5 * A,
    -0.5 * E,
    -0.5 * B,
    +0.5 * A,
    -0.5 * E,
    -0.5 * B, // 第六个平面（上）
  ]);
  //增加坐标点，坐标点是X,Y,Z的布局，可以自己任意设置
  bgeometry.setAttribute("position", new THREE.BufferAttribute(vertices, 3));
  bgeometry.computeVertexNormals();
  var mesh = new THREE.Mesh(bgeometry, material);
  mesh.castShadow = true; // 投射阴影
  var CenterX = 0.5 * (P1X + P2X);
  var CenterY = 0.5 * (P1Y + P2Y);
  var CenterZ = 0.5 * (P1Z + P2Z);
  mesh.translateX(CenterX);
  mesh.translateY(CenterY);
  mesh.translateZ(CenterZ);
  //var RotateAngelY = new THREE.Vector2(P4X - P3X, P4Z - P3Z);
  var RotateAngelY = new THREE.Vector2(P4Z - P3Z, P4X - P3X);
  mesh.rotateY(RotateAngelY.angle());
  var RotateAngelX = new THREE.Vector2(P1Y - P2Y, P2Z - P1Z);
  mesh.rotateX(RotateAngelX.angle());
  /*   var RotateAngelZ = new THREE.Vector2(P4Y - P3Y,P4X- P3X);
    mesh.rotateZ(RotateAngelZ.angle()); */
  /*   var RotateAngelX = new THREE.Vector2(P1Z - P2Z,P2Y-P1Y);
    mesh.rotateX(RotateAngelX.angle()-Math.PI*0.5); */

  return mesh;
}



export const circleBox = ({ bigRadius = 7, depth = 1, height = 15 }) => {
  let bigCircle = new THREE.Shape();
  bigCircle.moveTo(bigRadius * Math.cos(0), bigRadius * Math.sin(0));

  bigCircle.absarc(0, 0, bigRadius, 0, Math.PI, false);

  bigCircle.lineTo(bigRadius * Math.cos(Math.PI), -height);
  bigCircle.lineTo(bigRadius, -height);
  bigCircle.lineTo(bigRadius * Math.cos(0), bigRadius * Math.sin(0));
  let smallCircle = new THREE.Shape();

  smallCircle.arc(0, bigRadius / 3, bigRadius / 3, 0, Math.PI * 2, false);
  bigCircle.holes.push(smallCircle);
  let tube = new THREE.ExtrudeGeometry(bigCircle, {
    depth: depth,
    bevelEnabled: false,
    curveSegments: 100,
    steps: 1000,
  });

  let material = new THREE.MeshStandardMaterial({
    color: 0x00bfff,
    transparent: true,
    opacity: 0.5,
    side: THREE.DoubleSide,
  });

  let mesh = new THREE.Mesh(tube, material);
  let Group = new THREE.Group();
  Group.add(mesh);

  return Group;
};

export const preWeldedModel = ({
  width = 3,
  height = 1,
  depth = 3,
  radiusTop = 1,
  radiusBottom = 1,
  CylinderHeight = 4,
}) => {
  let cude = new THREE.BoxGeometry(width, height, depth);
  let material = new THREE.MeshLambertMaterial({
    color: 0x00bfff,
    transparent: true,
    opacity: 0.5,
  });
  let cudeMesh = new THREE.Mesh(cude, material);

  const geometry = new THREE.CylinderGeometry(
    radiusTop,
    radiusBottom,
    CylinderHeight,
    64
  );
  const cylinder = new THREE.Mesh(geometry, material);

  cylinder.position.y = -(CylinderHeight / 2);
  let signGroup = new THREE.Group();
  signGroup.add(cudeMesh);
  signGroup.add(cylinder);

  return signGroup;
};

export const circleHole = ({
  innerRadius = 5,
  outerRadius = 6,
  thetastart = 0,
  thetaLength = (Math.PI / 180) * 30,
  Bodydepth = 4,
}) => {
  let bigCircle = new THREE.Shape();
  bigCircle.moveTo(
    outerRadius * Math.cos(thetastart),
    outerRadius * Math.sin(thetastart)
  );

  bigCircle.absarc(
    0,
    0,
    outerRadius,
    thetastart,
    thetastart + thetaLength,
    false
  );
  bigCircle.lineTo(
    innerRadius * Math.cos(thetastart + thetaLength),
    innerRadius * Math.sin(thetastart + thetaLength)
  );
  bigCircle.absarc(
    0,
    0,
    innerRadius,
    thetastart + thetaLength,
    thetastart,
    true
  );
  bigCircle.lineTo(
    outerRadius * Math.cos(thetastart),
    outerRadius * Math.sin(thetastart)
  );

  let tube = new THREE.ExtrudeGeometry(bigCircle, {
    depth: Bodydepth,
    bevelEnabled: false,
    curveSegments: 100,
    steps: 1000,
  });

  let material = new THREE.MeshStandardMaterial({
    color: 0x00bfff,
    transparent: true,
    opacity: 0.5,
    side: THREE.DoubleSide,
  });

  let mesh = new THREE.Mesh(tube, material);
  let Group = new THREE.Group();
  Group.add(mesh);

  return Group;
};

export function AddNozzel(
  NPD,
  P1X,
  P1Y,
  P1Z,
  P2X,
  P2Y,
  P2Z,
  NozzleEndPrep,
  NozzleLength,
  material
) {
  var Cylinder1 = new THREE.CylinderGeometry(
    NPD * 0.5,
    NPD * 0.5,
    NozzleLength,
    32
  );
  var Mesh1 = new THREE.Mesh(Cylinder1, material);
  Mesh1.castShadow = true; // 投射阴影
  //初始化管口密封面位置
  Mesh1.position.set(0, -NozzleLength * 0.5, 0);
  // debugger;
  let wrapper = new THREE.Object3D();
  wrapper.add(Mesh1);
  if (NozzleEndPrep != "BE") {
    var Cylinder2 = new THREE.CylinderGeometry(
      NPD * 0.5 + 0.65,
      NPD * 0.5 + 0.65,
      0.5,
      32
    );
    var Mesh2 = new THREE.Mesh(Cylinder2, material);
    Mesh2.castShadow = true; // 投射阴影
    Mesh2.position.set(0, -0.25, 0);
    wrapper.add(Mesh2);
  }
  var quaternion = new THREE.Quaternion();
  quaternion.setFromUnitVectors(
    new Vector3(0, 1, 0),
    new Vector3(P1X - P2X, P1Y - P2Y, P1Z - P2Z).normalize()
  );
  wrapper.rotation.setFromQuaternion(quaternion);
  var MT43 = new THREE.Matrix4().setPosition(P1X, P1Y, P1Z);
  wrapper.applyMatrix4(MT43);
  return wrapper;
}

/**
 * 添加偏心椎壳
 * @param {*} P1X 1点X
 * @param {*} P1Y 1点y
 * @param {*} P1Z 1点z
 * @param {*} P2X 2点X
 * @param {*} P2Y 2点y
 * @param {*} P2Z 2点z
 * @param {*} A 参数A
 * @param {*} B 参数B
 * @param {*} C 参数C
 * @param {*} material 材质
 * @returns
 */
export function AddEccCone(P1X, P1Y, P1Z, P2X, P2Y, P2Z, A, B, C, material) {
  let wrapper = new THREE.Object3D();
  var dir = Math.abs(P1Y - P2Y) - A;
  for (let index = 0; index < 1000; index++) {
    var geometry = new THREE.CylinderGeometry(
      B * 0.5 - (B - C) * 0.5 * 0.001 * index,
      B * 0.5 - (B - C) * 0.5 * 0.001 * index,
      0.1,
      32
    );
    var circle = new THREE.Mesh(geometry, material);
    circle.castShadow = true; // 投射阴影
    circle.position.set(0, 0, 0);
    //计算转角
    var RotateAngelZ = new THREE.Vector2(0, P2X - P1X);
    if (dir == 0) {
      RotateAngelZ = new THREE.Vector2(1, 0);
    }
    //基于转角旋转，并设置到目标位置
    var MT41 = new THREE.Matrix4()
      .makeRotationAxis(new THREE.Vector3(0, 0, 1), RotateAngelZ.angle())
      .setPosition(
        P1X + (P2X - P1X) * 0.001 * index,
        P1Y + (P2Y - P1Y) * 0.001 * index,
        P1Z + (P2Z - P1Z) * 0.001 * index
      );
    circle.applyMatrix4(MT41);
    wrapper.add(circle);
  }
  /* var geometry = new THREE.CylinderGeometry(B * 0.5, B * 0.5, 0.001, 32);
  var circle = new THREE.Mesh(geometry, material);
  circle.castShadow = true; // 投射阴影
  circle.position.set(0, 0, 0);
  //计算转角
  var RotateAngelZ = new THREE.Vector2(0, P2X - P1X);
  var dir = Math.abs(P1Y - P2Y) - A;
  if (dir == 0) {
    RotateAngelZ = new THREE.Vector2(1, 0);
  }
  //基于转角旋转，并设置到目标位置
  var MT41 = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0, 0, 1), RotateAngelZ.angle()).setPosition(P1X, P1Y, P1Z);
  circle.applyMatrix4(MT41);
  wrapper.add(circle);*/
  return wrapper;
}

// export {
//   AddGround
// }
/* function addTextGeometry(text, index, material) {

  var geometry;
  import('node_modules/three/examples/jsm/oaders/FontLoader.js')
    .then((module) => {
      var loader = new FontLoader();

      loader.load('node_modules/three/examples/fonts/helvetiker_bold.typeface.json', function (font) {

        geometry = new THREE.TextBufferGeometry('Hello three.js!', {
          font: font,
          size: 80,
          height: 5,
          curveSegments: 12,
          bevelEnabled: true,
          bevelThickness: 10,
          bevelSize: 8,
          bevelSegments: 5
        });
        font.computeBoundingBox();

      });

    });
  var mesh = new THREE.Mesh(geometry, material);
  return mesh;

} */

/* function getTextCanvas(text) {
  var width = 512,
    height = 256;
  var canvas = document.createElement('canvas');
  canvas.width = width;
  canvas.height = height;
  var ctx = canvas.getContext('2d');
  ctx.fillStyle = '#C3C3C3';
  ctx.fillRect(0, 0, width, height);
  ctx.font = 50 + 'px " bold';
  ctx.fillStyle = '#2891FF';
  ctx.textAlign = 'center';
  //ctx.rotate(Math.PI);
  ctx.textBaseline = 'middle';
  ctx.fillText(text, width / 2, height / 2);
  return canvas;
} */
